package com.caregiver.watch.business.data.parser;

import com.caregiver.watch.business.care.service.strategy.HealthWarningStrategy;
import com.caregiver.watch.business.care.service.strategy.HealthWarningStrategyManage;
import com.google.protobuf.InvalidProtocolBufferException;
import com.caregiver.watch.business.data.protobuf.AlarmInfo;
import com.caregiver.watch.business.data.protobuf.RealtimeData;
import com.caregiver.watch.business.data.utils.time.DateTimeUtils;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Objects;

import static com.caregiver.watch.business.care.enums.HealthAlertTypeEnum.BLOOD_OXYGEN_WARNING;
import static com.caregiver.watch.business.care.enums.HealthAlertTypeEnum.BP_WARNING;
import static com.caregiver.watch.business.care.enums.HealthAlertTypeEnum.FALL_WARNING;
import static com.caregiver.watch.business.care.enums.HealthAlertTypeEnum.HEART_HEALTH_WARNING;
import static com.caregiver.watch.business.care.enums.HealthAlertTypeEnum.HEART_RATE_WARNING;
import static com.caregiver.watch.business.care.enums.HealthAlertTypeEnum.TEMPERATURE_WARNING;
import static com.caregiver.watch.business.data.enums.PayloadOptTypeProtoEnum.ALARM;


/**
 * 0x12协议解析
 */
@AllArgsConstructor
@Component
@Slf4j
public class NewAlarmDataParser implements IDataParser {

    private final HealthWarningStrategyManage healthWarningStrategyManage;

    @Override
    public Integer getOpt() {
        return ALARM.getOpt();
    }

    @Override
    public void dataParse(Long userId, String deviceId, byte[] payload) {
        AlarmInfo.Alarm_infokConfirm alarmInfokConfirm = null;
        try {
            alarmInfokConfirm = AlarmInfo.Alarm_infokConfirm.parseFrom(payload);
        } catch (InvalidProtocolBufferException ex) {
            log.error("parse alarm info error", ex);
            return;
        }
        if (alarmInfokConfirm.hasAlarm()) {
            AlarmInfo.HealthAlarmV3 alarmV3 = alarmInfokConfirm.getAlarm();

            // 解析设备发送的报警数据。当设备触发SOS警报（无电话功能）时，会包含GPS位置信息，
            // 代码遍历这些位置信息并记录日志，包括报警时间、经纬度和定位类型
            List<AlarmInfo.SOSGNSSINFOV3> sosAlarmList = alarmV3.getGnssinfoList();
            if (CollectionUtils.isNotEmpty(sosAlarmList)) {
                for (AlarmInfo.SOSGNSSINFOV3 sosAlarm : sosAlarmList) {
                    String alarmTime = DateTimeUtils.convert2DateTimeString(sosAlarm.getTimeStamp().getDateTime().getSeconds());
                    log.info("sos alarm time:{}, lat:{},lon:{},loc type:{}",
                            alarmTime, sosAlarm.getLatitude(), sosAlarm.getLongitude(), sosAlarm.getGpsType().ordinal());
                }
            }

            // 心率告警
            List<AlarmInfo.HrAlarmV3> hrAlarmList = alarmV3.getAlarmHrList();
            if (CollectionUtils.isNotEmpty(hrAlarmList)) {
                HealthWarningStrategy strategy = healthWarningStrategyManage.getStrategy(HEART_RATE_WARNING);
                if (Objects.nonNull(strategy)) {
                    strategy.handle(userId, deviceId, hrAlarmList);
                }
            }

            //血氧预警
            List<AlarmInfo.Spo2AlarmV3> spo2AlarmList = alarmV3.getAlarmSpo2List();
            if (CollectionUtils.isNotEmpty(spo2AlarmList)) {
                HealthWarningStrategy strategy = healthWarningStrategyManage.getStrategy(BLOOD_OXYGEN_WARNING);
                if (Objects.nonNull(strategy)) {
                    strategy.handle(userId, deviceId, spo2AlarmList);
                }
            }

            //心脏健康预警
            List<AlarmInfo.ThrombusAlarmV3> thrombusAlarmList = alarmV3.getAlarmThrombusList();
            if (CollectionUtils.isNotEmpty(thrombusAlarmList)) {
                HealthWarningStrategy strategy = healthWarningStrategyManage.getStrategy(HEART_HEALTH_WARNING);
                if (Objects.nonNull(strategy)) {
                    strategy.handle(userId, deviceId, thrombusAlarmList);
                }
            }

            // 跌倒预警
            List<AlarmInfo.FallAlarmConfV3> fallAlarmList = alarmV3.getAlarmFallList();
            if (CollectionUtils.isNotEmpty(fallAlarmList)) {
                HealthWarningStrategy strategy = healthWarningStrategyManage.getStrategy(FALL_WARNING);
                if (Objects.nonNull(strategy)) {
                    strategy.handle(userId, deviceId, fallAlarmList);
                }
            }

            // 体温预警
            List<AlarmInfo.TemperatureConf> tempAlarmList = alarmV3.getAlarmTemperatureList();
            if (CollectionUtils.isNotEmpty(tempAlarmList)) {
                HealthWarningStrategy strategy = healthWarningStrategyManage.getStrategy(TEMPERATURE_WARNING);
                if (Objects.nonNull(strategy)) {
                    strategy.handle(userId, deviceId, tempAlarmList);
                }
            }

            // 血压预警
            List<AlarmInfo.BpConf> bpAlarmList = alarmV3.getAlarmBpList();
            if (CollectionUtils.isNotEmpty(bpAlarmList)) {
                HealthWarningStrategy strategy = healthWarningStrategyManage.getStrategy(BP_WARNING);
                if (Objects.nonNull(strategy)) {
                    strategy.handle(userId, deviceId, bpAlarmList);
                }
            }

            //sos alarm, will send an alarm without location first, before do locate/call
            if (alarmV3.hasSOSNotificationTime()) {
                RealtimeData.DateTime sosTime = alarmV3.getSOSNotificationTime();
                String alarmTime = DateTimeUtils.convert2DateTimeString(sosTime.getDateTime().getSeconds());
                log.info("sos alarm time:{}", alarmTime);
            }

            //blood potassium alarm
            List<AlarmInfo.Blood_potassium_Conf> potassiumAlarmList = alarmV3.getAlarmBloodPotassiumList();
            if (potassiumAlarmList != null && potassiumAlarmList.size() > 0) {
                for (int i = 0; i < potassiumAlarmList.size(); i++) {
                    AlarmInfo.Blood_potassium_Conf postassiumAlarm = potassiumAlarmList.get(i);
                    String alarmTime = DateTimeUtils.convert2DateTimeString(postassiumAlarm.getTimeStamp().getDateTime().getSeconds());
                    log.info("blood potassium alarm time:{},potassium:{}", alarmTime, postassiumAlarm.getBloodPotassium());
                }
            }

            //blood sugar alarm
            List<AlarmInfo.Blood_sugar_Conf> sugarAlarmList = alarmV3.getAlarmBloodSugarList();
            if (sugarAlarmList != null && sugarAlarmList.size() > 0) {
                for (int i = 0; i < sugarAlarmList.size(); i++) {
                    AlarmInfo.Blood_sugar_Conf sugarAlarm = sugarAlarmList.get(i);
                    String alarmTime = DateTimeUtils.convert2DateTimeString(sugarAlarm.getTimeStamp().getDateTime().getSeconds());
                    log.info("blood sugar alarm time:{},bloodsugar:{}", alarmTime, sugarAlarm.getBloodSugar());
                }
            }

            //ecg patch fall off alarm
            List<AlarmInfo.ecg_Conf> ecgFallAlarmList = alarmV3.getAlarmEcgList();
            if (ecgFallAlarmList != null && ecgFallAlarmList.size() > 0) {
                for (int i = 0; i < ecgFallAlarmList.size(); i++) {
                    AlarmInfo.ecg_Conf ecgFalloffAlarm = ecgFallAlarmList.get(i);
                    String alarmTime = DateTimeUtils.convert2DateTimeString(ecgFalloffAlarm.getTimeStamp().getDateTime().getSeconds());
                    int ecg = (int) ecgFalloffAlarm.getEcg();
                    log.info("ecg patch fell off alarm time:{}, {}", alarmTime, ecg);
                }
            }
        }
        if (alarmInfokConfirm.hasAlarminfo()) {
            AlarmInfo.AlarminfoV3 infoV3 = alarmInfokConfirm.getAlarminfo();
            String alarmTime = DateTimeUtils.convert2DateTimeString(infoV3.getTimeStamp().getDateTime().getSeconds());
            //device in low power
            if (infoV3.hasLowpowerPercentage()) {
                log.info("low power time:{}, battery:{}", alarmTime, infoV3.getLowpowerPercentage());
            }
            //device is power off
            if (infoV3.hasPoweroffPercentage()) {
                log.info("power off time:{}, battery:{}", alarmTime, infoV3.getPoweroffPercentage());
            }
            //device not wear
            if (infoV3.hasWearstate()) {
                log.info("not wear time:{}", alarmTime);
            }
            //intercept call
            if (infoV3.hasInterceptNumber()) {
                log.info("intercept call time:{}, phone number:{}", alarmTime, infoV3.getInterceptNumber());
            }
        }
    }
}
